package com.ptma.model;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.List;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlElement;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.Nationalized;

/**
 * 
 * @author YahyaArshad
 * 
 */
@Entity
@Table(name = "USER")
public class User implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue
	@Column(name = "user_id")
	private Long id;

	@Column(name = "admin_id")
	private Long adminId;

	@XmlElement
	@Column(name = "email", unique = true, nullable = false, updatable = false)
	@Nationalized
	private String email;

	@Column(name = "company")
	private String company;

	@Column(nullable = false, name = "first_name")
	private String firstName;

	@Column(nullable = false, name = "last_name")
	private String lastName;

	@Column(nullable = false, name = "password")
	private String password;

	@Column(name = "register_time")
	private Timestamp registrationTime = new Timestamp(
			System.currentTimeMillis());

	@OneToMany
	@Cascade(value = { CascadeType.SAVE_UPDATE })
	@JoinColumn(name = "fk_user_id", referencedColumnName = "user_id", nullable = false, updatable = false)
	private Set<Group> groups;

	@OneToMany
	@Cascade(value = { CascadeType.SAVE_UPDATE })
	@JoinColumn(name = "fk_user_id", referencedColumnName = "user_id", nullable = false, updatable = false)
	private Set<Device> devices;

	@ManyToMany(fetch = FetchType.LAZY)
	@Cascade(value = CascadeType.SAVE_UPDATE)
	@JoinTable(name = "USER_ROLES", joinColumns = { @JoinColumn(name = "fk_user_id", nullable = false, updatable = false, referencedColumnName = "user_id") }, inverseJoinColumns = { @JoinColumn(name = "fk_role_id", nullable = false, updatable = false, referencedColumnName = "role_id") })
	private Set<Role> roles;

	@ManyToMany(fetch = FetchType.LAZY)
	@Cascade(value = CascadeType.SAVE_UPDATE)
	@JoinTable(name = "USER_APPLICATIONS", joinColumns = { @JoinColumn(name = "fk_user_id", nullable = false, updatable = false, referencedColumnName = "user_id") }, inverseJoinColumns = { @JoinColumn(name = "fk_application_id", nullable = false, updatable = false, referencedColumnName = "application_id") })
	private Set<Application> applications;

	public String getCompany() {
		return company;
	}

	public void setCompany(String company) {
		this.company = company;
	}

	public User() {

	}

	public void setGroups(Set<Group> groups) {
		this.groups = groups;
	}

	public Set<Group> getGroups() {
		return groups;
	}

	public User(String email) {
		this.email = email;
	}

	public Set<Application> getApplications() {
		return applications;
	}

	public void setApplications(Set<Application> applications) {
		this.applications = applications;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "First name: " + firstName + " :: Last name: " + lastName
				+ " :: Email: " + email;
	}

	public Long getAdminId() {
		return adminId;
	}

	public void setAdminId(Long adminId) {
		this.adminId = adminId;
	}

	public Set<Device> getDevices() {
		return devices;
	}

	public void setDevices(Set<Device> devices) {
		this.devices = devices;
	}

	@Override
	public int hashCode() {

		return id.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (null == obj || !(obj instanceof User)) {
			return false;
		}

		return this.id == ((User) obj).id;
	}

	public Set<Role> getRoles() {
		return roles;
	}

	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}

	public Timestamp getRegistrationTime() {
		return registrationTime;
	}

	public void setRegistrationTime(Timestamp registrationTime) {
		this.registrationTime = registrationTime;
	}

}
